<script setup lang="ts" name="WangEditor">
import '@wangeditor/editor/dist/css/style.css' // 引入 css
//@ts-ignore
import { Editor, Toolbar } from '@wangeditor/editor-for-vue' // 或者在global.d.ts中添加declare module '@wangeditor/editor-for-vue'
import type { IDomEditor, } from '@wangeditor/editor'
import { uploadImg } from '@/api/common/media'

/**
 * 组件传值
 */
interface Props {
  modelValue: string; // 声明modelValue，然后emit('update:modelValue'),可以实现双向绑定：v-model="xxx"
  text?: string;
  placeholder?: string;
  mode?: 'default' | 'simple';
  disable?: boolean;
  height?: string;
}
const props = withDefaults(defineProps<Props>(), {
  modelValue: '',
  text: '',
  placeholder: '请输入内容...',
  mode: 'default',
  disable: false,
  height: '400px'
})

/**
 * 定义事件
 */
const emit = defineEmits(['update:modelValue', 'update:text'])

const state = reactive({
  editorVal: props.modelValue, //编辑框内容
  editorConfig: {
    placeholder: props.placeholder,
    MENU_CONF: {} as any,
  },
  toolbarConfig: {},
})

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})

// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef()
const handleCreated = (editor: any) => {
  editorRef.value = editor // 记录 editor 实例，重要！
}

/**
 * 编辑内容区，改变内容触发
 */
const handelChange = (editor: IDomEditor) => {
  // console.log('editor', editor);
  emit('update:modelValue', editor.getHtml()) //HTML
  emit('update:text', editor.getText()) //文本内容
}

/**
 * 禁用
 */
watch(() => props.disable, (newVal) => {
  // console.log('newVal', newVal);
  nextTick(() => {
    const editor = editorRef.value
    if (editor == null) return
    newVal ? editor.disable() : editor.enable()
  })
}, {
  immediate: true
})

/**
 * 上传图片
 */
type InsertFnType = (url: string, alt: string, href: string) => void  // 声明上传图片成功后,进行回调显示的内容
state.editorConfig.MENU_CONF['uploadImage'] = {
  // 自定义上传
  async customUpload(file: File, insertFn: InsertFnType) {
    // file 即选中的文件
    // 自己实现上传，并得到图片 url alt href
    const form = new FormData()
    form.append('file', file)
    form.append('data', JSON.stringify({ sourceType: 'goods_img' }))
    const { data } = await uploadImg(form)
    // 最后插入图片
    insertFn(data.url, data.alt, data.href)
  }
}

</script>

<template>
  <div class="editor-container">
    <Toolbar class="editor-toolbar" :editor="editorRef" :defaultConfig="state.toolbarConfig" :mode="mode" />
    <Editor class="editor-area" :style="{ height }" v-model="state.editorVal" :defaultConfig="state.editorConfig"
      :mode="mode" @onCreated="handleCreated" @onChange="handelChange" />
  </div>
</template>

<style lang="scss" scoped>
// 暗黑模式样式见 dark.scss
.editor-container {
  .editor-toolbar {
    border: 1px solid var(--el-border-color-light) !important;
    border-radius: 3px 3px 0 0;
  }

  .editor-area {
    border: 1px solid var(--el-border-color-light) !important;
    border-radius: 0 0 3px 3px;
  }
}
</style>